	// verilator_coverage annotation
	module stage_id(
 020001	    input wire         clk,
%000001	    input wire         rst,
 118690	    input wire[31:0]   id_inst,
 000024	    input wire         w_regs_en,
 000081	    input wire[4:0]    w_regs_addr,
 000486	    input wire[31:0]   w_regs_data,
%000009	    input wire         ctrl_stall,
 112344	    output  wire[31:0] id_regs_data1,
 131974	    output  wire[31:0] id_regs_data2,
 000367	    output  wire[31:0] id_imm,
 000040	    output  wire[2:0]  id_func3_code, 
 006574	    output  wire       id_func7_code,
 019783	    output  wire[4:0]  id_rd,
 006584	    output  wire       id_br,
 000012	    output  wire       id_mem_read,
 000013	    output  wire       id_mem2reg,
 013198	    output  wire[2:0]  id_alu_op,
%000002	    output  wire       id_mem_write,
 000036	    output  wire[1:0]  id_alu_src1,
 000032	    output  wire[1:0]  id_alu_src2,
%000009	    output  wire       id_br_addr_mode,
 000022	    output  wire       id_regs_write,
	    //forwarding
 026347	    output  wire[4:0]  id_rs1,
 013233	    output  wire[4:0]  id_rs2,
	
	    //M matrix
%000003	    input  wire       w_m_en,
 000037	    input  wire[1:0]  w_m_index,
%000421	    input  wire[31:0] w_matrix_mopa[3:0],
%000003	    input  wire       w_matrix_mopa_en,
 000276	    output wire[31:0] id_m_data,
%000003	    output wire       id_m_write,
 006604	    output wire[1:0]  id_m_w_index,
 006611	    output wire[1:0]  id_m_r_index,
 026364	    output wire[6:0]  id_inst_opcode,
%000245	    output wire[31:0] id_r_matrix_mopa [3:0],
%000003	    output wire id_matrix_mopa_en,
	    // test6
%000003	    input wire me_matrix_mopa_en,
%000412	    input wire[31:0] me_matrix_mopa_o[3:0]
	
	);
	assign id_inst_opcode = id_inst[6:0];
	
 006584	wire        br          ;
 000012	wire        mem_read    ;
 000012	wire        mem2reg     ;
 013197	wire[2:0]   alu_op      ;
%000002	wire        mem_write   ;
 000035	wire[1:0]   alu_src1    ;
 000032	wire[1:0]   alu_src2    ;
%000000	wire        br_addr_mode;
 000022	wire        regs_write  ;
%000003	wire        m_write;
 000013	wire        m_read;
%000002	wire        matrix_mopa_en;
	
	assign matrix_mopa_en = (id_inst[6:0] == 7'b0001011 && id_inst[14:12] == 3'b100) ? 1'b1 : 1'b0;
	// st.tile or mov.tile rd, so read set 1
	assign m_read = (id_inst[6:0] == 7'b0001011 && (id_inst[14:12] == 3'b001 || id_inst[14:12] == 3'b011 || id_inst[14:12] == 3'b100)) ? 1'b1 : 0;
	matrix_regs m_regs(
	    .clk(clk),
	    .rst(rst),
	    .w_m_en(w_m_en),
	    .r_m_en(m_read),
	    .w_m_index(w_m_index),
	    .r_m_index(id_inst[21:20]),
	    .w_m_data(w_regs_data),
	    .r_m_data(id_m_data),
	    .w_matrix_mopa_en(w_matrix_mopa_en),
	    .w_matrix_mopa(w_matrix_mopa),
	    .r_matrix_mopa(id_r_matrix_mopa),
	    .me_matrix_mopa_o(me_matrix_mopa_o),
	    .me_matrix_mopa_en(me_matrix_mopa_en)
	);
	
	regs u_regs(
	    .clk          (clk              ),
	    .rst          (rst              ),
	    .r_regs_addr1 (id_inst[19:15]   ),
	    .r_regs_addr2 (id_inst[24:20]   ),
	    .w_regs_addr  (w_regs_addr      ),
	    .w_regs_data  (w_regs_data      ),
	    .w_regs_en    (w_regs_en        ),
	    .r_regs_o1    (id_regs_data1    ),
	    .r_regs_o2    (id_regs_data2    )
	);
	
	ctrl u_ctrl(
	    .inst_fun (id_inst[14:12]),
	    .inst_op        (id_inst[6:0] ),
	    .br             (br           ),
	    .mem_read       (mem_read     ),
	    .mem2reg        (mem2reg      ),
	    .alu_op         (alu_op       ),
	    .mem_write      (mem_write    ),
	    .alu_src1       (alu_src1     ),
	    .alu_src2       (alu_src2     ),
	    .br_addr_mode   (br_addr_mode ),
	    .regs_write     (regs_write   ),
	    .m_write        (m_write)
	);
	
	imm_gen u_imm_gen(
	    .inst  (id_inst  ),
	    .imm_o (id_imm   )
	);
	
	assign id_rd         = id_inst[11:7];
	assign id_func3_code = id_inst[14:12];
	assign id_func7_code = id_inst[30];
	
	assign id_rs1 = id_inst[19:15];
	assign id_rs2 = id_inst[24:20];
	
	//stall
	assign id_br           = (ctrl_stall == 1) ? 0 : br             ;
	assign id_mem_read     = (ctrl_stall == 1) ? 0 : mem_read       ;       
	assign id_mem2reg      = (ctrl_stall == 1) ? 0 : mem2reg        ;      
	assign id_alu_op       = (ctrl_stall == 1) ? 0 : alu_op         ;     
	assign id_mem_write    = (ctrl_stall == 1) ? 0 : mem_write      ;            
	assign id_alu_src1     = (ctrl_stall == 1) ? 0 : alu_src1       ;
	assign id_alu_src2     = (ctrl_stall == 1) ? 0 : alu_src2       ; 
	assign id_br_addr_mode = (ctrl_stall == 1) ? 0 : br_addr_mode   ;       
	assign id_regs_write   = (ctrl_stall == 1) ? 0 : regs_write     ;      
	assign id_m_write      = (ctrl_stall == 1) ? 0 : m_write        ;       
	assign id_m_w_index      = (ctrl_stall == 1) ? 0 : id_inst[8:7]   ;
	assign id_m_r_index      = (ctrl_stall == 1) ? 0 : id_inst[21:20]   ;
	assign id_matrix_mopa_en = (ctrl_stall == 1) ? 0 : matrix_mopa_en;
	
	endmodule
	
